﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DevExpress.Internal;
using DevExpress.Utils;

namespace EFERP.Implements
{
    public class ERPDb : DbContext
    {
        public ERPDb() : this(null, null) { }
        public ERPDb(string connectionString) : base(connectionString) { }
        public ERPDb(string filePath, string databaseName) : this(GetConnectionString(filePath, databaseName)) { }

        public DbSet<code> codes { get; set; }
        public DbSet<company> companies { get; set; }
        public DbSet<dic_allowance> dic_allowance { get; set; }
        public DbSet<dic_degree> dic_degree { get; set; }
        public DbSet<dic_education> dic_education { get; set; }
        public DbSet<dic_ethnic> dic_ethnic { get; set; }
        public DbSet<dic_group_rate> dic_group_rate { get; set; }
        public DbSet<dic_holiday> dic_holiday { get; set; }
        public DbSet<dic_hospital> dic_hospital { get; set; }
        public DbSet<dic_informatic> dic_informatic { get; set; }
        public DbSet<dic_job> dic_job { get; set; }
        public DbSet<dic_language> dic_language { get; set; }
        public DbSet<dic_machine> dic_machine { get; set; }
        public DbSet<dic_minimumsalary> dic_minimumsalary { get; set; }
        public DbSet<dic_nationality> dic_nationality { get; set; }
        public DbSet<dic_pit> dic_pit { get; set; }
        public DbSet<dic_position> dic_position { get; set; }
        public DbSet<dic_professional> dic_professional { get; set; }
        public DbSet<dic_province> dic_province { get; set; }
        public DbSet<dic_rate> dic_rate { get; set; }
        public DbSet<dic_relative> dic_relative { get; set; }
        public DbSet<dic_religion> dic_religion { get; set; }
        public DbSet<dic_salary_formula> dic_salary_formula { get; set; }
        public DbSet<dic_salary_rank> dic_salary_rank { get; set; }
        public DbSet<dic_salary_step> dic_salary_step { get; set; }
        public DbSet<dic_school> dic_school { get; set; }
        public DbSet<dic_shift> dic_shift { get; set; }
        public DbSet<dic_signer> dic_signer { get; set; }
        public DbSet<dic_skill> dic_skill { get; set; }
        public DbSet<dic_state> dic_state { get; set; }
        public DbSet<dic_symbol> dic_symbol { get; set; }
        public DbSet<dic_timekeeper_formula> dic_timekeeper_formula { get; set; }
        public DbSet<dic_unit> dic_unit { get; set; }
        public DbSet<hrm_branch> hrm_branch { get; set; }
        public DbSet<hrm_candidate> hrm_candidate { get; set; }
        public DbSet<hrm_candidate_mark> hrm_candidate_mark { get; set; }
        public DbSet<hrm_candidate_rate> hrm_candidate_rate { get; set; }
        public DbSet<hrm_contract> hrm_contract { get; set; }
        public DbSet<hrm_department> hrm_department { get; set; }
        public DbSet<hrm_department_rate> hrm_department_rate { get; set; }
        public DbSet<hrm_discipline> hrm_discipline { get; set; }
        public DbSet<hrm_employee> hrm_employee { get; set; }
        public DbSet<hrm_employee_activity> hrm_employee_activity { get; set; }
        public DbSet<hrm_employee_allowance> hrm_employee_allowance { get; set; }
        public DbSet<hrm_employee_relative> hrm_employee_relative { get; set; }
        public DbSet<hrm_employee_schedule> hrm_employee_schedule { get; set; }
        public DbSet<hrm_evaluationboard> hrm_evaluationboard { get; set; }
        public DbSet<hrm_group> hrm_group { get; set; }
        public DbSet<hrm_group_rate> hrm_group_rate { get; set; }
        public DbSet<hrm_insurance> hrm_insurance { get; set; }
        public DbSet<hrm_insurance_declaration> hrm_insurance_declaration { get; set; }
        public DbSet<hrm_insurance_modify> hrm_insurance_modify { get; set; }
        public DbSet<hrm_insurance_process> hrm_insurance_process { get; set; }
        public DbSet<hrm_insurance_tablelist> hrm_insurance_tablelist { get; set; }
        public DbSet<hrm_payinsurance_c66ahd> hrm_payinsurance_c66ahd { get; set; }
        public DbSet<hrm_payinsurance_c67ahd> hrm_payinsurance_c67ahd { get; set; }
        public DbSet<hrm_payinsurance_c68ahd> hrm_payinsurance_c68ahd { get; set; }
        public DbSet<hrm_payinsurance_c69ahd> hrm_payinsurance_c69ahd { get; set; }
        public DbSet<hrm_payinsurance_tablelist> hrm_payinsurance_tablelist { get; set; }
        public DbSet<hrm_position_rate> hrm_position_rate { get; set; }
        public DbSet<hrm_process_accident> hrm_process_accident { get; set; }
        public DbSet<hrm_process_advance> hrm_process_advance { get; set; }
        public DbSet<hrm_process_assignment> hrm_process_assignment { get; set; }
        public DbSet<hrm_process_breakwork> hrm_process_breakwork { get; set; }
        public DbSet<hrm_process_confirmtimekeeper> hrm_process_confirmtimekeeper { get; set; }
        public DbSet<hrm_process_discipline> hrm_process_discipline { get; set; }
        public DbSet<hrm_process_petition> hrm_process_petition { get; set; }
        public DbSet<hrm_process_position> hrm_process_position { get; set; }
        public DbSet<hrm_process_rate> hrm_process_rate { get; set; }
        public DbSet<hrm_process_ratedetail> hrm_process_ratedetail { get; set; }
        public DbSet<hrm_process_reward> hrm_process_reward { get; set; }
        public DbSet<hrm_process_salary> hrm_process_salary { get; set; }
        public DbSet<hrm_process_training> hrm_process_training { get; set; }
        public DbSet<hrm_product> hrm_product { get; set; }
        public DbSet<hrm_product_group> hrm_product_group { get; set; }
        public DbSet<hrm_product_state> hrm_product_state { get; set; }
        public DbSet<hrm_recruitment> hrm_recruitment { get; set; }
        public DbSet<hrm_reward> hrm_reward { get; set; }
        public DbSet<hrm_reward_employee> hrm_reward_employee { get; set; }
        public DbSet<hrm_salary> hrm_salary { get; set; }
        public DbSet<hrm_salary_allowance> hrm_salary_allowance { get; set; }
        public DbSet<hrm_salary_bydepartment> hrm_salary_bydepartment { get; set; }
        public DbSet<hrm_salary_minus> hrm_salary_minus { get; set; }
        public DbSet<hrm_salary_pay> hrm_salary_pay { get; set; }
        public DbSet<hrm_salary_plus> hrm_salary_plus { get; set; }
        public DbSet<hrm_salary_tablelist> hrm_salary_tablelist { get; set; }
        public DbSet<hrm_subsidiary> hrm_subsidiary { get; set; }
        public DbSet<hrm_timekeeper> hrm_timekeeper { get; set; }
        public DbSet<hrm_timekeeper_break> hrm_timekeeper_break { get; set; }
        public DbSet<hrm_timekeeper_extra> hrm_timekeeper_extra { get; set; }
        public DbSet<hrm_timekeeper_furlough> hrm_timekeeper_furlough { get; set; }
        public DbSet<hrm_timekeeper_machine> hrm_timekeeper_machine { get; set; }
        public DbSet<hrm_timekeeper_overtime> hrm_timekeeper_overtime { get; set; }
        public DbSet<hrm_timekeeper_private> hrm_timekeeper_private { get; set; }
        public DbSet<hrm_timekeeper_shift> hrm_timekeeper_shift { get; set; }
        public DbSet<hrm_timekeeper_table> hrm_timekeeper_table { get; set; }
        public DbSet<hrm_timekeeper_tablelist> hrm_timekeeper_tablelist { get; set; }
        public DbSet<hrm_timekeeper_total> hrm_timekeeper_total { get; set; }
        public DbSet<hrm_training> hrm_training { get; set; }
        public DbSet<hrm_training_employee> hrm_training_employee { get; set; }
        public DbSet<hrm_welfare> hrm_welfare { get; set; }
        public DbSet<hrm_work> hrm_work { get; set; }
        public DbSet<hrm_work_employee> hrm_work_employee { get; set; }
        public DbSet<keycode> keycodes { get; set; }
        public DbSet<license> licenses { get; set; }
        public DbSet<soft> softs { get; set; }
        public DbSet<sys_company> sys_company { get; set; }
        public DbSet<sys_group> sys_group { get; set; }
        public DbSet<sys_group_object> sys_group_object { get; set; }
        public DbSet<sys_info> sys_info { get; set; }
        public DbSet<sys_log> sys_log { get; set; }
        public DbSet<sys_object> sys_object { get; set; }
        public DbSet<sys_option> sys_option { get; set; }
        public DbSet<sys_rule> sys_rule { get; set; }
        public DbSet<sys_user> sys_user { get; set; }
        public DbSet<sys_user_rule> sys_user_rule { get; set; }
        public DbSet<wpm_comment> wpm_comment { get; set; }
        public DbSet<wpm_milestone> wpm_milestone { get; set; }
        public DbSet<wpm_milestone_attachment> wpm_milestone_attachment { get; set; }
        public DbSet<wpm_priority> wpm_priority { get; set; }
        public DbSet<wpm_project> wpm_project { get; set; }
        public DbSet<wpm_reminder> wpm_reminder { get; set; }
        public DbSet<wpm_status> wpm_status { get; set; }
        public DbSet<wpm_task> wpm_task { get; set; }
        public DbSet<wpm_task_attachment> wpm_task_attachment { get; set; }
        public DbSet<soft_update> soft_update { get; set; }


        #region ConnectionString
        static string connectionString;

        static string GetConnectionString(string filePath, string databaseName)
        {
            if (connectionString != null) return connectionString;
            if (filePath == null)
                filePath = DataDirectoryHelper.GetFileLocalCopy("DevAV.mdf", DataDirectoryHelper.DataFolderName);
            if (databaseName == null)
                databaseName = Path.GetFileNameWithoutExtension(filePath);
            string rawConnectionString = string.Format("Data Source=.\\SQLEXPRESS;Integrated Security=True;MultipleActiveResultSets=True;database={0};Application Name=EntityFrameworkMUE;AttachDbFileName={1};Connection Timeout=90", databaseName, filePath);
            connectionString = DbEngineDetector.PatchConnectionString(rawConnectionString);
            RecoverDatabase(connectionString);
            DataDirectoryHelper.GetFileLocalCopy("DevAV.mdf", DataDirectoryHelper.DataFolderName);
            return connectionString;
        }
        static void RecoverDatabase(string connectionString)
        {
            string databaseName;
            using (SqlConnection sqlConnection = new SqlConnection(GetMasterConnectionString(connectionString, out databaseName)))
            {
                sqlConnection.Open();
                DropDatabase(databaseName, sqlConnection);
            }
        }
        static string GetMasterConnectionString(string connectionString, out string databaseName)
        {
            var builder = new DbConnectionStringBuilder { ConnectionString = connectionString };
            databaseName = (string)builder["database"];
            builder["database"] = null;
            builder["AttachDbFileName"] = null;
            builder["initial catalog"] = "master";
            return builder.ConnectionString;
        }
        static string GetMdfFilePath(string databaseName, SqlConnection sqlConnection)
        {
            using (SqlCommand sqlCommand = new SqlCommand(string.Format("SELECT * FROM master.dbo.sysdatabases WHERE name=\'{0}\'", databaseName), sqlConnection))
            {
                try
                {
                    using (SqlDataReader reader = sqlCommand.ExecuteReader())
                    {
                        return reader.Read() ? reader.GetString(10) : null;
                    }
                }
                catch (SqlException)
                {
                    return null;
                }
            }
        }
        static void DropDatabase(string databaseName, SqlConnection sqlConnection)
        {
            using (SqlCommand sqlCommand = new SqlCommand("DROP DATABASE " + databaseName, sqlConnection))
            {
                try
                {
                    sqlCommand.ExecuteNonQuery();
                }
                catch (SqlException) { }
            }
        }
        #endregion
    }
}
